package cn.com.css.taxInspection.common.aop.aspect;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import cn.com.css.taxInspection.common.aop.annotation.LogAnnotation;
import cn.com.css.taxInspection.system.entity.SysLog;
import cn.com.css.taxInspection.system.mapper.SysLogMapper;
import cn.com.css.taxInspection.system.service.impl.HttpSessionService;
import cn.com.css.taxInspection.util.HttpContextUtils;
import cn.com.css.taxInspection.util.IPUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

/**
 * 日志切面
 *
 */
@Aspect
@Component
@Slf4j
public class SysLogAspect {
    @Lazy
    @Resource
    private SysLogMapper sysLogMapper;

    @Lazy
    @Resource
    private HttpSessionService httpSessionService;

    /**
     * 此处的切点是注解的方式 只要出现 @LogAnnotation注解都会进入
     */
    @Pointcut("@annotation(cn.com.css.taxInspection.common.aop.annotation.LogAnnotation)")
    public void logPointCut() {

    }

    /**
     * 环绕增强,相当于MethodInterceptor
     */
    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long beginTime = System.currentTimeMillis();
        // 执行方法
        Object result = point.proceed();
        // 执行时长(毫秒)
        long time = System.currentTimeMillis() - beginTime;

        // 保存日志
        try {
            saveSysLog(point, time);
        } catch (Exception e) {
            log.error("sysLog,exception:{}", e, e);
        }

        return result;
    }

    //保存系统日志
    private void saveSysLog(ProceedingJoinPoint joinPoint, long time) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        SysLog sysLog = new SysLog();
        LogAnnotation logAnnotation = method.getAnnotation(LogAnnotation.class);
        if (logAnnotation != null) {
            // 注解上的描述
            sysLog.setOperation(logAnnotation.title() + "-" + logAnnotation.action());
        }
        // 请求的方法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        sysLog.setMethod(className + "." + methodName + "()");
        log.info("请求{}.{}耗时{}毫秒", className, methodName, time);
        if (!"importByajbh".equals(methodName)) {
            try {
                // 请求的参数
                Object[] args = joinPoint.getArgs();
                String params = null;
                if (args.length != 0) {
                    // 过滤不可序列化的字段，例如 MultipartFile
                    List<Object> filteredArgs = new ArrayList<>();
                    for (Object arg : args) {
                        if (arg instanceof MultipartFile) {
                            filteredArgs.add("MultipartFile [hidden]");
                        } else {
                            filteredArgs.add(arg);
                        }
                    }
                    // 将过滤后的参数序列化
                    params = JSON.toJSONString(filteredArgs);
                }
                sysLog.setParams(params);
            } catch (Exception e) {
                log.error("sysLog,exception:{}", e, e);
            }
        }

        // 获取request
        HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
        // 设置IP地址
        sysLog.setIp(IPUtils.getIpAddr(request));
        log.info("Ip{}，接口地址{}，请求方式{}，入参：{}", sysLog.getIp(), request.getRequestURL(), request.getMethod(),
                sysLog.getParams());
        // 用户名
        String userId = httpSessionService.getCurrentUserId();
        String username = httpSessionService.getCurrentUsername();
        // TODO
        if (org.springframework.util.StringUtils.isEmpty(userId)
                && org.springframework.util.StringUtils.isEmpty(username)) {
            if (!org.springframework.util.StringUtils.isEmpty(sysLog.getParams())) {
                // 用户退出方法
                // 记录微信小程序
                JSONArray params = JSONObject.parseArray(sysLog.getParams());
                JSONObject json = (JSONObject) JSONObject.toJSON(params.get(0));
                sysLog.setUsername(String.valueOf(json.get("username")));
                sysLog.setUserId(String.valueOf(json.get("password")));
            }
        } else {
            sysLog.setUsername(username);
            sysLog.setUserId(userId);
            sysLog.setTaxorgcode(httpSessionService.getCurrentDeptId());

        }
        sysLog.setTime((int) time);
        log.info(sysLog.toString());
        sysLogMapper.insert(sysLog);

    }
}
